/*   _________  __  ____________  ___   ___  ____
 *  / ___/ __ \/  |/  /_  __/ _ \/ _ | / _ \/ __/
 * / /__/ /_/ / /|_/ / / / / , _/ __ |/ // / _/  
 * \___/\____/_/  /_/ /_/ /_/|_/_/ |_/____/___/  
 * COMTRADE file parser
 * -------------------------------------------------------------------------
 * Copyright (C) 2013 - Ericson Norberto A Santos (ericsonnorberto@gmail.com)
 * Federal University Of Campina Grande - UFCG
 * 
 * Supports on IEEE Std C37.111-1999 COMTRADE-99 and IEEE Std C37.111-1991
 * COMTRADE-91 standards.
 * 
 * ABSTRACT:
 * A common format for data files and exchange medium used for the interchange
 * of various types of fault, test, or simulation data for electrical power
 * systems is defined. Sources of transient data are described, and the case of
 * diskettes as an exchange medium is recommended.
 * Issues of sampling rates, filters, and sample rate conversions for transient
 * data being exchanged are discussed. Files for data exchange are specified,
 * as is the organization of the data. A sample file is given.
 * 
 * License information:
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
*/
#include <cstdlib>
#include <vector>

#include "COMTRADE_parse.hpp"

using namespace std;

struct TMP_A_B
{
    double a;
    double b;
};
typedef TMP_A_B temp_a_b;

int main(int argc, char** argv)
{
    /* COMTRADE object */
    COMTRADE_parse mf;
    
    /* Open files */
    mf.COMTRADE_open_file("./files/131126,034558355000,-03t,LGZ,05C4_LGZ-SOB,CHESF,131126035742");
    mf.COMTRADE_parse_cfg_file();
    
    /* Test of general information */
    cout << "cfg_data_station_name      " << mf.COMTRADE_get_cfg_general_information(cfg_data_station_name)     << endl;
    cout << "cfg_data_rec_dev_id        " << mf.COMTRADE_get_cfg_general_information(cfg_data_rec_dev_id)       << endl;
    cout << "cfg_data_rev_year          " << mf.COMTRADE_get_cfg_general_information(cfg_data_rev_year)         << endl;
    
    /* Test of a/d channel information */
    cout << "cfg_data_ch_tt             " << mf.COMTRADE_get_cfg_ad_channel_information(cfg_data_ch_tt)         << endl;
    cout << "cfg_data_ch_ta             " << mf.COMTRADE_get_cfg_ad_channel_information(cfg_data_ch_ta)         << endl;
    cout << "cfg_data_ch_td             " << mf.COMTRADE_get_cfg_ad_channel_information(cfg_data_ch_td)         << endl;
    
    /* Test of analog channels */
    cout << "cfg_data_a_ch_id           " << mf.COMTRADE_get_cfg_analog_channel_s(2, cfg_data_a_ch_id)          << endl;
    cout << "cfg_data_a_ch_phase        " << mf.COMTRADE_get_cfg_analog_channel_s(2, cfg_data_a_ch_phase)       << endl;
    cout << "cfg_data_a_ch_ccbm         " << mf.COMTRADE_get_cfg_analog_channel_s(2, cfg_data_a_ch_ccbm)        << endl;
    cout << "cfg_data_a_ch_units        " << mf.COMTRADE_get_cfg_analog_channel_s(2, cfg_data_a_ch_units)       << endl;
    cout << "cfg_data_a_ch_PS           " << mf.COMTRADE_get_cfg_analog_channel_s(2, cfg_data_a_ch_PS)          << endl;
    cout << "cfg_data_a_ch_a            " << mf.COMTRADE_get_cfg_analog_channel_d(2, cfg_data_a_ch_a)           << endl;
    cout << "cfg_data_a_ch_b            " << mf.COMTRADE_get_cfg_analog_channel_d(2, cfg_data_a_ch_b)           << endl;
    cout << "cfg_data_a_ch_skew         " << mf.COMTRADE_get_cfg_analog_channel_d(2, cfg_data_a_ch_skew)        << endl;
    cout << "cfg_data_a_ch_pri_v        " << mf.COMTRADE_get_cfg_analog_channel_d(2, cfg_data_a_ch_pri_v)       << endl;
    cout << "cfg_data_a_ch_sec_v        " << mf.COMTRADE_get_cfg_analog_channel_d(2, cfg_data_a_ch_sec_v)       << endl;
    cout << "cfg_data_a_ch_min          " << mf.COMTRADE_get_cfg_analog_channel_i(2, cfg_data_a_ch_min)         << endl;
    cout << "cfg_data_a_ch_max          " << mf.COMTRADE_get_cfg_analog_channel_i(2, cfg_data_a_ch_max)         << endl;
    
    /* Test of digital channels */
    cout << "cfg_data_d_ch_id           " << mf.COMTRADE_get_cfg_digital_channel(1, cfg_data_d_ch_id)           << endl;
    cout << "cfg_data_d_ch_phase        " << mf.COMTRADE_get_cfg_digital_channel(1, cfg_data_d_ch_phase)        << endl;
    cout << "cfg_data_d_ch_ccbm         " << mf.COMTRADE_get_cfg_digital_channel(1, cfg_data_d_ch_ccbm)         << endl;
    
    /* Test of digital channel status */
    cout << "channel_status             " << mf.COMTRADE_get_cfg_digital_channel_status(1)                      << endl;
    
    /* Test of line frequency */
    cout << "line_frequency             " << mf.COMTRADE_get_cfg_line_frequency()                               << endl;
    
    /* Test of sampling rate */
    cout << "sampling_rate              " << mf.COMTRADE_get_cfg_sampling_rate()                                << endl;
    cout << "cfg_data_nrates            " << mf.COMTRADE_get_cfg_sampling_rate_data(cfg_data_nrates)            << endl;
    cout << "cfg_data_endsamp           " << mf.COMTRADE_get_cfg_sampling_rate_data(cfg_data_endsamp)           << endl;
    
    /* Test of date and time */
    cout << "cfg_data_dt-cfg_data_hr    " << mf.COMTRADE_get_cfg_time_stamp(cfg_data_dt_dd) << "/"              << mf.COMTRADE_get_cfg_time_stamp(cfg_data_dt_mm) << "/" << mf.COMTRADE_get_cfg_time_stamp(cfg_data_dt_yy) << " "
                                          << mf.COMTRADE_get_cfg_time_stamp(cfg_data_hr_hh) << ":"              << mf.COMTRADE_get_cfg_time_stamp(cfg_data_hr_mm) << ":" << mf.COMTRADE_get_cfg_time_stamp(cfg_data_hr_ss) << endl;
    cout << "cfg_data_trig_dt           " << mf.COMTRADE_get_cfg_time_stamp(cfg_data_trig_dt_dd) << "/"         << mf.COMTRADE_get_cfg_time_stamp(cfg_data_trig_dt_mm) << "/" << mf.COMTRADE_get_cfg_time_stamp(cfg_data_trig_dt_yy) << " "
                                          << mf.COMTRADE_get_cfg_time_stamp(cfg_data_trig_hr_hh) << ":"         << mf.COMTRADE_get_cfg_time_stamp(cfg_data_trig_hr_mm) << ":" << mf.COMTRADE_get_cfg_time_stamp(cfg_data_trig_hr_ss) << endl;
    
    /* Test of file type */
    cout << "file_type                  " << mf.COMTRADE_get_cfg_file_type()                                    << endl;
    
    /* Test of time multiplier */
    cout << "time_multiplier            " << mf.COMTRADE_get_cfg_time_multiplier()                              << endl;

    mf.COMTRADE_parse_dat_file();
    
    /* Test */
    cout << "total_records              " << mf.COMTRADE_get_dat_total_records() << endl;
    cout << "size_of_file               " << mf.COMTRADE_get_dat_size_of_file() << endl;

    /*========================================================================*/
    /* MATLAB GRAPHICS ANALYSER                                               */
    /*========================================================================*/
    vector<temp_a_b> multiplier_a_b;
    
    for (int m=0; m<mf.COMTRADE_get_cfg_ad_channel_information(cfg_data_ch_ta); m++)
    {
        temp_a_b temp_ab;
        temp_ab.a = mf.COMTRADE_get_cfg_analog_channel_d(m+1, cfg_data_a_ch_a);
        temp_ab.b = mf.COMTRADE_get_cfg_analog_channel_d(m+1, cfg_data_a_ch_b);
        multiplier_a_b.push_back(temp_ab);
        cout << "channel                    " << m+1 << " a=" << temp_ab.a << " b=" << temp_ab.b << endl;        
    }
    double sample_time = 0;
    

    ofstream file_out;
    
    /* Open file stream */
    file_out.open("./sample.m", ios::out);
    
    file_out << "clear all; close all; clc" << endl;
    file_out << "data_bin = [" << endl;
    for (int i=0; i<mf.COMTRADE_get_dat_total_records(); i++)
    {
        /* Time stamp */
        file_out << mf.COMTRADE_get_dat_time_stamp(i+1)*(1e-6) << " ";
        
        /* Sample data */
        for (int j=0; j<mf.COMTRADE_get_cfg_ad_channel_information(cfg_data_ch_ta); j++)
        {
//            sample_time = (mf.COMTRADE_get_dat_analog_channel_sample(i+1, j+1, 0)*multiplier_a_b[j].a)
//                          +multiplier_a_b[j].b;
//            file_out << sample_time
//                     << " ";
            file_out << mf.COMTRADE_get_dat_analog_channel_sample(i+1, j+1, 0)
                     << " ";
        }
        file_out << ";" << endl;
    }
    file_out << "];" << endl;
   
    for (int k=0; k<mf.COMTRADE_get_cfg_ad_channel_information(cfg_data_ch_ta); k++)
    {
        file_out << "data_ch" << k+1 << "_x = data_bin(1:" << mf.COMTRADE_get_dat_total_records() << ", 1);" << endl;
        file_out << "data_ch" << k+1 << "_y = data_bin(1:" << mf.COMTRADE_get_dat_total_records() << ", " << k+2 << ");" << endl << endl;
        file_out << "figure(" << k+1 << ");" << endl;
        file_out << "plot(data_ch" << k+1 << "_x, data_ch" << k+1 << "_y), grid" << endl;
        file_out << "title ('" << mf.COMTRADE_get_cfg_analog_channel_s(k+1, cfg_data_a_ch_id)
                 << " (" << mf.COMTRADE_get_cfg_analog_channel_s(k+1, cfg_data_a_ch_units) << ")');"
                 << endl << endl;
    }
    
    /* Close file stream */
    file_out.close();
    
    //mf.comtrade_teste();
    
    
    return EXIT_SUCCESS;
}

